﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace PuzzleCoop
{
    public class Player : Character
    {
        public int playerIndex;
        public bool isCasting = false;
        public int castTime = 1;
        public double castTimer = 0;

        public Point CoordE;
        public Vector2 DrawPositionE = Vector2.Zero;

        Texture2D cursorPE;
        Texture2D iconPA;
        Texture2D blockSelectedPA;
        Texture2D blockSelectedPE;

        Block selectedBlock = null;

        SpriteSheet spriteSheet;

        Texture2D spriteUp;
        Texture2D spriteDown;
        Texture2D spriteLeft;
        Texture2D spriteRight;

        public Player(PlayScreen playScreen, int playerIndex)
            : base(playScreen, GameScreenManager.Load<Texture2D>("Images\\Characters\\a"))
        {
            this.playerIndex = playerIndex;
            position = new Vector2(Slot.SizeA / 2, Slot.SizeA / 2);
            drawPosition = new Vector2(1280 / 4, 720 / 2);
            CoordE = new Point(0, 0);
            DrawPositionE = new Vector2(3 * 1280 / 4, 720 / 2);
            cursorPE = GameScreenManager.Load<Texture2D>("Images\\Board\\PE\\cursorPE");
            iconPA = GameScreenManager.Load<Texture2D>("Images\\Board\\PE\\iconPA");
            blockSelectedPA = GameScreenManager.Load<Texture2D>("Images\\Board\\PA\\blockSelectedPA");
            blockSelectedPE = GameScreenManager.Load<Texture2D>("Images\\Board\\PE\\blockSelectedPE");
            spriteSheet = new SpriteSheet(this, 4, 100);
            spriteUp = GameScreenManager.Load<Texture2D>("Images\\Characters\\PA\\pa_up");
            spriteDown = GameScreenManager.Load<Texture2D>("Images\\Characters\\PA\\pa_down");
            spriteLeft = GameScreenManager.Load<Texture2D>("Images\\Characters\\PA\\pa_left");
            spriteRight = GameScreenManager.Load<Texture2D>("Images\\Characters\\PA\\pa_right");
        }

        public override void Update(GameTime gameTime)
        {
            spriteSheet.Update(gameTime);
            
            if (selectedBlock != null) selectedBlock.coord = CoordE;
            PAMove(Input.LeftStickState(playerIndex));
            if (Input.RightStickState(playerIndex) != Vector2.Zero) direction = Input.RightStickState(playerIndex); //GameScreenManager.MousePos - this.position; // atualiza a direção e, consequentemente, a rotação ao ser desenhado
            
            base.Update(gameTime);
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            Point coordPA = playScreen.board.GetCoord(position);

            // Desenha o bloco selecionado pelo PE na visão do PA
            if (selectedBlock != null)
            {
                Point p = selectedBlock.coord;
                if (p.X > coordPA.X - 2 && p.X < coordPA.X + 2 && p.Y > coordPA.Y - 2 && p.Y < coordPA.Y + 2)
                {
                    Vector2 selectedPos = playScreen.board.DrawPositionA + new Vector2(CoordE.X * Slot.SizeA, CoordE.Y * Slot.SizeA) - selectedBlock.originA;
                    selectedBlock.DrawA(spriteBatch, playScreen.board.DrawPositionA);
                    spriteBatch.Draw(blockSelectedPA, selectedPos, null, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
                }
            }

            // Desenha o PA
            //base.Draw(spriteBatch);
            Texture2D temp = temp = spriteDown;
            if (direction == Direction.Up) temp = spriteUp;
            //else if (direction == Direction.Down) temp = spriteDown;
            else if (direction == Direction.Right) temp = spriteRight;
            else if (direction == Direction.Left) temp = spriteLeft;
            spriteBatch.Draw(temp, drawPosition, sourceRectangle, Color.White, 0, origin, scale, SpriteEffects.None, 0);
        }

        public void DrawE(SpriteBatch spriteBatch)
        {
            Point coordPA = playScreen.board.GetCoord(position);

            // Desenha o bloco selecionado pelo PE na visão do PE
            if (selectedBlock != null)
            {
                selectedBlock.DrawE(spriteBatch, playScreen.board.DrawPositionE);
                spriteBatch.Draw(blockSelectedPE, playScreen.board.DrawPositionE + new Vector2(CoordE.X * Slot.SizeE, CoordE.Y * Slot.SizeE) - selectedBlock.originE, Color.White);
            }

            // Desenha o cursor do PE
            spriteBatch.Draw(cursorPE, DrawPositionE, Color.White);

            // Desenha o indicador do PA na visão do PE
            Vector2 iconPApos = DrawPositionE + new Vector2((coordPA.X - CoordE.X) * Slot.SizeE, (coordPA.Y - CoordE.Y) * Slot.SizeE);
            if (iconPApos.X > 640 && iconPApos.Y > 20)
                spriteBatch.Draw(iconPA, iconPApos, Color.White);
        }

        public void PAMove(Vector2 d)
        {
            if (isCasting) return;
            Move(d);
        }

        public void PEMove(Point p)
        {
            Point newCoordE = new Point(CoordE.X + p.X, CoordE.Y + p.Y);
            newCoordE.X = (int)MathHelper.Clamp(newCoordE.X, 0, Board.Size.X - 1);
            newCoordE.Y = (int)MathHelper.Clamp(newCoordE.Y, 0, Board.Size.Y - 1);
            if (selectedBlock == null) { CoordE = newCoordE; return; }
            Slot slot = playScreen.board.map[newCoordE.X, newCoordE.Y];
            if (slot == null || !(slot is EmptySlot)) return;

            // move todos os objetos do slot selecionado
            foreach (GameObject go in playScreen.gameObjects)
            {
                if (playScreen.board.GetCoord(go.position) != CoordE) continue;
                Vector2 newPos = go.position;
                newPos.X += (newCoordE.X - CoordE.X) * Slot.SizeA;
                newPos.Y += (newCoordE.Y - CoordE.Y) * Slot.SizeA;
                go.position = newPos;
            }
            CoordE = newCoordE;
        }

        public void SelectSlot()
        {
            if (selectedBlock == null)
            {
                Slot slot = playScreen.board.map[CoordE.X, CoordE.Y];
                if (!(slot is Block) || playScreen.board.GetCoord(position) == slot.coord)
                {
                    // TO-DO: mensagem e som de erro
                    return;
                }
                selectedBlock = slot as Block;
                playScreen.board.map[CoordE.X, CoordE.Y] = new EmptySlot(CoordE);
            }
            else
            {
                selectedBlock.sourceRectangle.Width = selectedBlock.textureA.Width;
                playScreen.board.map[CoordE.X, CoordE.Y] = selectedBlock;
                selectedBlock = null;
            }
        }

        public bool Cast(int castTime)
        {
            if (isCasting) return false;
            isCasting = true;
            this.castTime = castTime;
            return true;
        }
    }
}
